#ifndef OA_CORE_TASKMANAGER_H
#define OA_CORE_TASKMANAGER_H

#include "libs.h"
#include "util.h"
#include "core/event.h"
#include "core/task.h"

namespace core {
	class _OA_export TaskManager {
	public:
		typedef boost::shared_ptr<Task> TaskPtr;
		typedef util::ConcurrentQueue<TaskPtr> TaskList;
	
		struct StopEvent {};
	
		TaskManager(unsigned int numThreads = 0); //0 for autodetect
		~TaskManager();
	
		void add(TaskPtr task);
	
		void start();
		void stop();
	
		void handle(const StopEvent& );
		void handle(const Task::TaskCompleted& tc);
	
	private:
		void worker();
		void execute(TaskPtr task);
		void synchronize();
	
		boost::thread_group mThreads;
		unsigned int mNumThreads;
	
		mutable bool mRunning;
		EventChannel mChan;
	
		TaskList mTaskList[2];
		TaskList mBackgroundTasks;
		TaskList mSyncTasks;
	
		unsigned int mReadList;
		unsigned int mWriteList;
	
		typedef boost::mutex Mutex;
		typedef boost::condition_variable Condition;
		typedef Mutex::scoped_lock ScopedLock;
	
		mutable Mutex mSyncMutex;
		Condition mCondition;
		unsigned int mNumTasksToWaitFor;
	};
}

#endif
